#include "MapEditor.h"

//includes mutuos


#include "Gui.h"
Gui *gui;
#include "Tools/ToolAddObject.h"
ToolAddObject *addTool;
#include "Tools/ToolRotateObject.h"
ToolRotateObject *rotateTool;
#include "Tools/ToolMoveObject.h"
ToolMoveObject *moveTool;
#include "Tools/ToolRemoveObject.h"
ToolRemoveObject *removeTool;
#include "Tools/ToolCopyObject.h"
ToolCopyObject *copyTool;
#include "Tools/ToolScaleObject.h"
ToolScaleObject *scaleTool;

using namespace Ogre;

MapEditor::MapEditor(){}

void MapEditor::start(){
	go();
	setInterfaceActivated(true);
}

MapEditor::~MapEditor(void){    
	/*
	delete mListener;    
	mSceneMgr->destroyQuery(mRaySceneQuery);
	mInputManager->destroyInputObject(mKeyboard);
	mInputManager->destroyInputObject(mMouse);
	OIS::InputManager::destroyInputSystem(mInputManager);

	delete mRoot;
	delete cameraTool;
	*/
}

void MapEditor::createFrameListener(){

	noTool = new Tool();
	mListener = new BufferedInputHandler(mKeyboard, mMouse,noTool);
	mRoot->addFrameListener(mListener);
	cameraTool = new ToolMoveCamera(mCamera);

}


void MapEditor::createScene()
{

	//mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager");
	mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE,"Default SceneManager");


	mCamera = mSceneMgr->createCamera("PlayerCam"); 
	Viewport *vp = mRoot->getAutoCreatedWindow()->addViewport(mCamera );
    mCamera->setNearClipDistance(5);
//    mCamera->setCollisionEnabled(false);
//    mCamera->getRealCamera()->setQueryFlags(0);
	// Set camera look point

	createTerrain();
	mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));

    SceneNode *node;

    // create the light
    Light *light = mSceneMgr->createLight("Light1");
    light->setType(Light::LT_POINT);
    light->setPosition(Vector3(250, 150, 250));
    light->setDiffuseColour(ColourValue::White);
    light->setSpecularColour(ColourValue::White);

    // Create the scene node
    node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode1", Vector3(-400, 200, 400));
	node->setPosition(40, 100, 580);
	node->yaw(Degree(-45));


    // Create the pitch node
    node = node->createChildSceneNode("PitchNode1");
    node->attachObject(mCamera);

    // create the second camera node/pitch node
    node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode2", Vector3(0, 200, 400));
    node = node->createChildSceneNode("PitchNode2");

	// Populate the camera and scene manager containers
    mCamNode = mCamera->getParentSceneNode();
	
	mSceneMgr->setSkyBox(true, (Constants::instance()->getSkyBoxName()).c_str());
	
	mRaySceneQuery = mSceneMgr->createRayQuery(Ray());

}

void MapEditor::createTerrain(){

	
	// Fog
    // NB it's VERY important to set this before calling setWorldGeometry 
    // because the vertex program picked will be different

	mSceneMgr->setWorldGeometry("..\\..\\media\\terrain.cfg");
    // Infinite far plane?
    if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
    {
        mCamera->setFarClipDistance(0);
    }

    // Define the required skyplane
    Plane plane;
    // 5000 world units from the camera
    plane.d = 5000;
    // Above the camera, facing down
    plane.normal = -Vector3::UNIT_Y;
		
}

void MapEditor::setupCEGUI(){

	gui= new Gui(mRoot, this);
}

void MapEditor::toolEnded(){
	
	mListener->changeTool(noTool);
	setInterfaceActivated(true);
}

void MapEditor::addModel(CEGUI::String path){

	std::string oName = path.c_str();
	if(addTool)
		delete addTool;
	addTool = new ToolAddObject(mCamera,mSceneMgr,oName,mRaySceneQuery);

	mListener->changeTool(addTool);
	setInterfaceActivated(false);
}

void MapEditor::startMovingObject(){

	if(!moveTool)
		moveTool = new ToolMoveObject(mCamera,mSceneMgr,mRaySceneQuery);

	mListener->changeTool(moveTool);
	setInterfaceActivated(false);
	gui->setMouseVisible(true);
	gui->centerMouse();
}

void MapEditor::startScalingObject(){

	if(!scaleTool)
		scaleTool = new ToolScaleObject(mCamera,mSceneMgr,mRaySceneQuery);

	mListener->changeTool(scaleTool);
	setInterfaceActivated(false);
	gui->setMouseVisible(true);
	gui->centerMouse();
}

void MapEditor::startRotatingObject(){

	if(!rotateTool)
		rotateTool = new ToolRotateObject(mCamera,mSceneMgr,mRaySceneQuery);
		
	mListener->changeTool(rotateTool);
	setInterfaceActivated(false);
	gui->setMouseVisible(true);
	gui->centerMouse();
}

void MapEditor::startDuplicatingObject(){

	if(!copyTool)
		copyTool = new ToolCopyObject(mCamera,mSceneMgr,mRaySceneQuery);

	mListener->changeTool(copyTool);
	setInterfaceActivated(false);
	gui->setMouseVisible(true);
	gui->centerMouse();
}

void MapEditor::startRemovingObject(){

	if(!removeTool)
		removeTool = new ToolRemoveObject(mCamera,mSceneMgr,mRaySceneQuery);

	mListener->changeTool(removeTool);
	setInterfaceActivated(false);
	gui->setMouseVisible(true);
	gui->centerMouse();
}

void MapEditor::quit(){
	mListener->quit();
}

void MapEditor::setInterfaceActivated(bool b){
	
	mListener->sendEventsToCEGUI(b);
	gui->setSheetVisible(b);
	gui->setMouseVisible(b);
}